use std::rc::Rc;

fn main() {
    println!("============================");
    test01_shared_list();
    println!("============================");
    test02_count();
    println!("============================");
}

#[derive(Debug)]
enum List {
    Cons(i32, Rc<List>),
    Nil,
}

fn test01_shared_list() {
    use crate::List::{Cons, Nil};
    let a = Rc::new(Cons(1, Rc::new(Cons(2, Rc::new(Cons(3, Rc::new(Nil)))))));
    let b = Rc::new(Cons(4, Rc::clone(&a)));
    let c = Rc::new(Cons(5, Rc::clone(&a)));
    println!("{b:?}");
    println!("{c:?}");
}

fn test02_count() {
    use crate::List::{Cons, Nil};
    let a = Rc::new(Cons(5, Rc::new(Cons(10, Rc::new(Nil)))));
    println!("count after creating a = {}", Rc::strong_count(&a));
    let b = Cons(3, Rc::clone(&a));
    println!("count after creating b = {}", Rc::strong_count(&a));
    {
        let c = Cons(4, Rc::clone(&a));
        println!("count after creating c = {}", Rc::strong_count(&a));
    }
    println!("count after c goes out of scope = {}", Rc::strong_count(&a));
}
